package org.linlinjava.litemall.wx.annotation.support;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.db.domain.LitemallToken;
import org.linlinjava.litemall.db.service.LitemallTokenService;
import org.linlinjava.litemall.db.util.SpringUtils;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.service.UserTokenManager;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;


public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    public static final String LOGIN_TOKEN_KEY = "X-Litemall-Token";


    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(Integer.class) && parameter.hasParameterAnnotation(LoginUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
        try{
            String token = StringUtils.isNotBlank(request.getHeader(LOGIN_TOKEN_KEY))?request.getHeader(LOGIN_TOKEN_KEY):request.getParameter(LOGIN_TOKEN_KEY);
            if (token == null || token.isEmpty()) {
                return null;
            }
            LitemallTokenService litemallTokenService = (LitemallTokenService) SpringUtils.getBean("litemallTokenService");
//            Integer userId = UserTokenManager.getUserId(token);
            LitemallToken tokenUserId = litemallTokenService.getOne(Wrappers.lambdaQuery(LitemallToken.class)
                    .eq(LitemallToken::getToken, token));
            //判断token是否失效 是否被挤下线
            LitemallToken litemallToken = litemallTokenService.getOne(Wrappers.lambdaQuery(LitemallToken.class)
                    .eq(LitemallToken::getToken, token)
                    .eq(LitemallToken::getUserId, tokenUserId.getUserId()));
            // 获取当前时间
            LocalDateTime currentTime = LocalDateTime.now();
            // 获取令牌过期时间
            LocalDateTime expireTime = litemallToken.getExpireTime();
            // 计算离过期还剩余的天数
            long daysUntilExpiration = ChronoUnit.DAYS.between(currentTime, expireTime);
            // 如果离过期还剩7天，则重新添加30天时间
            if (daysUntilExpiration > 7) {
                litemallToken.setExpireTime(LocalDateTime.now().plusDays(30));
                litemallTokenService.updateById(litemallToken);
            }
            //失效token已经被清除
            if(ObjectUtil.isNull(litemallToken)){
                return null;
            }
            //账号被挤下线或者被系统禁用
            if(litemallToken.getValid()==1||litemallToken.getValid()==2){
                //清除令牌
                litemallTokenService.removeById(litemallToken);
                return null;
            }
            //到了过期时间
            if(litemallToken.getExpireTime().isBefore(LocalDateTime.now())){
                //清除令牌
                litemallTokenService.removeById(litemallToken);
                return null;
            }
            return tokenUserId.getUserId();
        }catch (Exception e){
            return null;
        }
    }
}
